package drds.binlog.database_driver.packets.server;

import drds.binlog.common.Authors;
import drds.binlog.database_driver.packets.HeaderPacket;
import drds.binlog.database_driver.packets.PacketWithHeaderPacket;
import drds.binlog.database_driver.utils.Bytes;
import drds.binlog.database_driver.utils.MSC;
import drds.common.Author;
import lombok.Getter;
import lombok.Setter;

import java.io.IOException;

/**
 * MySQL Handshake Initialization Packet.<br>
 */
@Author(name = Authors.LI_YANG)
public class HandshakeInitializationPacket extends PacketWithHeaderPacket
{


    @Setter
    @Getter
    public byte protocolVersion = MSC.default_protocol_version;
    @Setter
    @Getter
    public String serverVersion;
    @Setter
    @Getter
    public long threadId;
    @Setter
    @Getter
    public byte[] seed;
    @Setter
    @Getter
    public int serverCapabilities;
    @Setter
    @Getter
    public byte serverCharsetNumber;
    @Setter
    @Getter
    public int serverStatus;
    @Setter
    @Getter
    public byte[] restOfScrambleBuff;

    public HandshakeInitializationPacket()
    {
    }

    public HandshakeInitializationPacket(HeaderPacket headerPacket)
    {
        super(headerPacket);
    }

    /**
     * <pre>
     * Bytes                        Name
     *  -----                        ----
     *  1                            protocol_version
     *  n (Null-Terminated String)   server_version
     *  4                            thread_id
     *  8                            scramble_buff
     *  1                            (filler) always 0x00
     *  2                            server_capabilities
     *  1                            server_language
     *  2                            server_status
     *  13                           (filler) always 0x00 ...
     *  13                           rest of scramble_buff (4.1)
     * </pre>
     */
    public void fromBytes(byte[] bytes)
    {
        int index = 0;
        // 1. read protocol_version
        protocolVersion = bytes[index];
        index++;

        // 2. read server_version
        byte[] serverVersionBytes = Bytes.readNullTerminatedBytes(bytes, index);
        serverVersion = new String(serverVersionBytes);
        index += (serverVersionBytes.length + 1);//end with null

        // 3. read thread_id
        threadId = Bytes.readUnsigned4IntLittleEndian(bytes, index);
        index += 4;

        // 4. read scramble_buff
        seed = Bytes.readFixedLengthBytes(bytes, index, 8);
        index += 8;

        index += 1; // 1 byte (filler) always 0x00

        // 5. read server_capabilities
        this.serverCapabilities = Bytes.readUnsigned2IntLittleEndian(bytes, index);
        index += 2;

        // 6. read server_language
        this.serverCharsetNumber = bytes[index];
        index++;

        // 7. read server_status
        this.serverStatus = Bytes.readUnsigned2IntLittleEndian(bytes, index);
        index += 2;

        // 8. bypass filtered bytes
        index += 13;
        // 9. read rest of scramble_buff
        this.restOfScrambleBuff = Bytes.readFixedLengthBytes(bytes, index, 12); // 虽然Handshake
        //left scrumble 13 bytes
        // Initialization
        // Packet规定最后13个byte是剩下的scrumble,
        // 但实际上最后一个字节是0, 不应该包含在scrumble中.
        // end read
    }

    /**
     * Bypass implementing it, 'cause nowhere to use it.
     */
    public byte[] toBytes() throws IOException
    {
        return null;
    }

}
